import { defineComponent, nextTick, reactive } from "vue";
import { useCommonApi } from "/@/api/CommonApi";
import { ElMessage, ElMessageBox } from "element-plus";
import DataModule from "/@/common/data/DataModule";
import StringUtils from "/@/common/StringUtils";
import TimeUtils from "/@/common/TimeUtils";
import { IGetListParams } from "/@/api/dataProvider/types";
import { create, deleteMany, getList, update } from "/@/api/dataProvider";
import { ComponentInternalInstance } from "vue";
import { useMultiTagsStoreHook } from "/@/store/modules/multiTags";
import { useRoute, useRouter } from "vue-router";
import { useRuleStoreHook } from "/@/store/modules/rules";

export interface CommonNextProp {
  detailDialogTile?: string;
  editDialogTitle?: string;
  editRule?: any;
  addRule?: any;
  addDialogTitle?: string;
  tableAlias: string;
  isCustomList?: boolean;
  getTableList?: Function;
  instance: ComponentInternalInstance;
  isList?: boolean;
  primaryKey: any;
  parentRoute?: string;
}
const CommonNext = defineComponent({
  name: "commonNext",
  setup(props: any) {
    const CommonObj = reactive({
      // 表单禁用字段数组
      disableField: [],
      // 表单校验规则
      formRules: {},
      // 表名
      tableAlias: "",
      // 表格加载动画
      loading: false,
      // 初始化axios数据
      commonApi: useCommonApi,
      // 搜索数据
      searchForm: {},
      // 初始化新增，修改表单数据
      formData: {},
      // 初始化表头数据
      tableHead: [],
      tableList: [],
      // 初始化表排序字段
      SortChange: "descending",
      sort: "",
      order: "",
      // 选中数据的id数组
      selectIds: [],
      // 分页
      currentPage: 1,
      pageSizes: [10, 20, 50, 100],
      pageSize: 10,
      total: 0,
      selectList: [],

      // 是否显示新增表单
      dialogCreateFormVisible: false,
      // 表单标题
      dialogTitle: "新增记录",
      formType: 1,
      // 批量更新模态框
      batchVisible: false,
      // 批量新增模态框
      batchSaveDialogVisible: false,
      // 批量提交按钮loading效果
      batchCommitLoading: false,
      // 可编辑表格list
      editList: [],
      // 可编辑表格复选框List
      editTableSelectList: []
    });

    // 关闭批量新增模态框方法
    const beforeSaveDialogCancel = () => {
      if (CommonObj.editList.length > 0) {
        ElMessageBox.confirm(
          "关闭弹窗后所有表格数据都将遗失, 是否继续?",
          "提示",
          {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning"
          }
        ).then(() => {
          CommonObj.batchSaveDialogVisible = false;
        });
      } else {
        CommonObj.batchSaveDialogVisible = false;
      }
    };

    // 展示批量新增模态框
    const showBatchAdd = () => {
      CommonObj.editList = [];
      CommonObj.batchSaveDialogVisible = true;
    };

    // 查询表格
    const query = () => {
      CommonObj.currentPage = 1;
      acquireTable();
    };

    const acquireTable = () => {
      const page: IGetListParams = {
        pageNum: CommonObj.currentPage,
        pageSize: CommonObj.pageSize,
        sortField: CommonObj.sort,
        order: CommonObj.order
      };
      const search: DataModule = DataModule.formatToModul(
        CommonObj.searchForm,
        CommonObj.tableHead
      );
      getTableList(props.tableAlias, page, search);
    };

    const resetSearch = () => {
      CommonObj.searchForm = {};
      acquireTable();
    };

    // 获取数据list
    const getTableList = async (
      resource: any,
      page: IGetListParams,
      search: DataModule
    ) => {
      if (props.isList) {
        CommonObj.loading = false;
      } else if (props.isCustomList) {
        CommonObj.loading = true;
        const { data } = await props.getTableList(resource, page, search);
        if (data.code === 0) {
          CommonObj.tableList = data.data.list;
          CommonObj.total = data.data.total;
        } else {
          ElMessage.error(data.msg);
        }
        CommonObj.loading = false;
      } else {
        CommonObj.loading = true;
        getList(resource, page, search)
          .then(res => {
            CommonObj.tableList = res.list;
            CommonObj.total = res.total;
          })
          .finally(() => {
            CommonObj.loading = false;
          });
      }
    };

    // 获取表头及字段信息
    const acquireTableInfo = async (tableAlias: any) => {
      CommonObj.loading = true;
      await CommonObj.commonApi.getTableInfo(tableAlias).then(ref => {
        if (ref.data.code === 0) {
          CommonObj.tableHead = ref.data.data.fieldList;
          (CommonObj as any).primaryKey = ref.data.data.tablePk;
        }
      });
    };
    // 获取基表信息用于格式化下拉框及表格数据
    const getBaseTableInfo = async () => {
      const set = new Set();
      for (let i = 0; i < CommonObj.tableHead.length; i++) {
        if (StringUtils.isNotEmpty(CommonObj.tableHead[i].fkTable)) {
          set.add(CommonObj.tableHead[i].fkTable);
        }
      }
      const arr: any[] = [];
      for (const item of set) {
        arr.push(item);
      }
      if (arr.length > 0) {
        await CommonObj.commonApi.getBaseTableInfo(arr.toString()).then(ref => {
          if (ref.data.code === 0) {
            const data = ref.data.data;
            for (let i = 0; i < CommonObj.tableHead.length; i++) {
              if (StringUtils.isNotEmpty(CommonObj.tableHead[i].fkTable)) {
                const fkTable: string = CommonObj.tableHead[i].fkTable;
                const list = data[fkTable];
                const selectList: any[] = [];
                for (let k = 0; k < list.length; k++) {
                  let param;
                  if (CommonObj.tableHead[i].fkKey) {
                    param = {
                      selectKey: list[k][CommonObj.tableHead[i].fkKey],
                      selectValue: list[k][CommonObj.tableHead[i].fkValue]
                    };
                  } else {
                    param = {
                      selectKey: list[k].BASE_NAME,
                      selectValue: list[k].BASE_VALUE
                    };
                  }
                  selectList.push(param);
                }
                CommonObj.tableHead[i].selectList = selectList;
              }
            }
          } else {
            console.log("获取基表信息出错");
          }
        });
      }
    };

    // 表格排序
    const handleSortChange = (val: any) => {
      CommonObj.SortChange = val;
      CommonObj.sort = (CommonObj.SortChange as any).prop;
      if ((CommonObj.SortChange as any).order === "descending") {
        CommonObj.order = "DESC";
      } else {
        CommonObj.order = "ASC";
      }
      acquireTable();
    };

    // 分页
    const handleSizePagChange = (val: number) => {
      CommonObj.pageSize = val;
      acquireTable();
    };

    const handleCurrentPagChange = (val: number) => {
      CommonObj.currentPage = val;
      acquireTable();
    };

    const showEdit = (row: any) => {
      const obj = Object.assign({}, row);
      useRuleStoreHook().clearAll();
      for (const [key, val] of Object.entries(obj)) {
        if (key.indexOf("time") || key.indexOf("TIME")) {
          obj[key] = val + "";
        }
      }
      const typename = props.tableAlias;
      const addTitle = props.editDialogTitle;
      useMultiTagsStoreHook().handleTags("push", {
        path: `${props.parentRoute}${typename}/edit`,
        parentPath: route.matched[0].path,
        name: `${typename}Edit`,
        query: { typename },
        meta: {
          title: {
            zh: addTitle,
            en: `Edit Info`
          },
          showLink: false,
          i18n: false,
          dynamicLevel: 3
        }
      });
      useRuleStoreHook().setRules(props.editRule);
      useRuleStoreHook().setTitle(addTitle);
      useRuleStoreHook().setTypeName(typename);
      useRuleStoreHook().setValue(obj);
      useRuleStoreHook().setPk(props.primaryKey);
      router.push({
        name: `${typename}Edit`,
        query: { typename },
        params: {
          title: addTitle
        }
      });
    };

    const showAdd = () => {
      useRuleStoreHook().clearAll();
      const typename = props.tableAlias;
      const addTitle = props.addDialogTitle;
      useMultiTagsStoreHook().handleTags("push", {
        path: `${props.parentRoute}/${typename}/add`,
        parentPath: route.matched[0].path,
        name: `${typename}Add`,
        query: { typename },
        meta: {
          title: {
            zh: addTitle,
            en: `Add Info`
          },
          showLink: false,
          i18n: false,
          dynamicLevel: 3
        }
      });
      useRuleStoreHook().setRules(props.addRule);
      useRuleStoreHook().setTitle(addTitle);
      useRuleStoreHook().setTypeName(typename);
      router.push({
        name: `${typename}Add`,
        query: { typename },
        params: { title: addTitle }
      });
    };

    // 展示批量修改弹窗方法
    const showBatchUpdate = () => {
      if (CommonObj.selectIds.length === 0) {
        ElMessage.warning("请选择需批量修改的资料");
      } else {
        CommonObj.formType = 3;
        CommonObj.formData = {};
        CommonObj.batchVisible = true;
      }
    };

    // 关闭弹窗方法
    const cancelForm = () => {
      nextTick(() => {
        CommonObj.formData = {};
        const ref: any = props.instance.refs.formCo;
        ref.$refs.formCommon.resetFields();
        ref.$refs.formCommon.clearValidate();
      }).then(() => {
        CommonObj.dialogCreateFormVisible = false;
      });
    };

    // 关闭批量更新模态框方法
    const cancelBatchForm = () => {
      CommonObj.formData = {};
      (CommonObj as any).$nextTick(() => {
        const ref: any = (CommonObj as any).$refs.batchForm;
        ref.$refs.formCommon.resetFields();
      });
      CommonObj.batchVisible = false;
    };
    // 表单提交事件
    const formSubmit = (value: any) => {
      const { val, type } = value;
      nextTick(() => {
        // 获取虚拟dom
        const ref: any = props.instance.refs.formCo;
        ref.$refs[val].validate((valid: boolean) => {
          const form: any = Object.assign({}, CommonObj.formData);
          // 校验表带校验规则
          if (valid) {
            if (type === 1) {
              create(props.tableAlias, form).then(() => {
                acquireTable();
                cancelForm();
              });
            } else if (type === 2) {
              delete form.password;
              update(props.tableAlias, form).then(() => {
                acquireTable();
                cancelForm();
              });
            }
          }
        });
      });
    };

    // 批量更新方法
    const formBatchSubmit = (value: any) => {
      const { val } = value;
      nextTick(() => {
        const ref: any = props.instance.refs.batchForm;
        ref.$refs[val].validate((valid: boolean) => {
          const form: any = Object.assign({}, CommonObj.formData);
          if (valid) {
            form[(CommonObj as any).primaryKey] =
              CommonObj.selectIds.toString();
            CommonObj.commonApi
              .updateBatchWithDate(CommonObj.tableAlias, form)
              .then(ref => {
                if (ref.data.code === 0) {
                  ElMessage.success("批量修改成功");
                  acquireTable();
                  cancelBatchForm();
                } else {
                  ElMessage.error("批量修改失败");
                }
              });
          }
        });
      });
    };
    // 表格复选框选中改变监听事件
    const handleSelectionChange = (val: any) => {
      const list: Array<any> = [];
      for (let i = 0; i < val.length; i++) {
        list[i] = val[i][(CommonObj as any).primaryKey];
      }
      CommonObj.selectIds = list;
      CommonObj.selectList = val;
    };

    // 批量删除方法
    const deleteData = () => {
      if (CommonObj.selectIds.length === 0) {
        ElMessage.warning("请选择要删除的资料");
      } else {
        ElMessageBox.confirm("是否确定删除选中记录?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        })
          .then(() => {
            deleteMany(props.tableAlias, CommonObj.selectIds).then(() => {
              acquireTable();
            });
          })
          .catch(() => {
            ElMessage.info("取消删除");
          });
      }
    };

    // 格式化表格数据
    const tableFormatter = (row: any, column: any, cellValue: any): any => {
      let key: any = null;
      CommonObj.tableHead.forEach((val: any) => {
        if (column.property === val.fieldName) {
          if (val.javaType === "Boolean") {
            let tValue: any = null;
            let fValue: any = null;
            val.selectList.forEach((child: any) => {
              let value = child.selectValue;
              if (val.javaType === "Integer") {
                value = +value;
              }
              if (value === "true") {
                tValue = child.selectKey;
              } else {
                fValue = child.selectKey;
              }
            });
            if (cellValue) {
              key = tValue;
            } else {
              key = fValue;
            }
          } else if (val.webType === "el-select" || val.webType === "tree") {
            val.selectList.forEach((child: any) => {
              let value = child.selectValue;
              if (val.javaType === "Integer") {
                value = +value;
                cellValue = +cellValue;
              }
              if (cellValue === value) {
                key = child.selectKey;
              }
            });
          }
          if (val.javaType === "datetime") {
            if (StringUtils.isNotEmpty(cellValue)) {
              cellValue = +cellValue;
              key = TimeUtils.dateFtt(
                "yyyy-MM-dd hh:mm:ss",
                new Date(cellValue)
              );
            }
          }
          if (val.javaType === "date") {
            if (StringUtils.isNotEmpty(cellValue)) {
              cellValue = +cellValue;
              key = TimeUtils.dateFtt("yyyy-MM-dd", new Date(cellValue));
            }
          }
        }
      });
      if (key !== null) {
        return key;
      } else {
        return cellValue;
      }
    };

    // 批量提交
    const batchSaveSubmit = () => {
      if (CommonObj.editList.length > 0) {
        CommonObj.batchCommitLoading = true;
        const list: any[] = [];
        let isEdit = false;
        CommonObj.editList.forEach(value => {
          if (value.edit) {
            isEdit = true;
          } else {
            const param = Object.assign({}, value);
            delete param.index;
            delete param.edit;
            list.push(param);
          }
        });
        if (isEdit) {
          ElMessage.warning("表格中还有未保存的数据！");
          CommonObj.batchCommitLoading = false;
        } else {
          CommonObj.commonApi
            .saveBatchWithDate(CommonObj.tableAlias, JSON.stringify(list))
            .then(ref => {
              if (ref.data.code === 0) {
                ElMessage.success("新增成功");
                CommonObj.batchCommitLoading = false;
                acquireTable();
                CommonObj.batchSaveDialogVisible = false;
              } else {
                ElMessage.warning("新增失败");
              }
            });
        }
      } else {
        ElMessage.warning("请添加记录");
      }
    };
    const router = useRouter();
    const route = useRoute();

    const showDetails = (row: any) => {
      useRuleStoreHook().clearAll();
      const obj = Object.assign({}, row);
      for (const [key, val] of Object.entries(obj)) {
        if (key.indexOf("time") || key.indexOf("TIME")) {
          obj[key] = val + "";
        }
      }
      const typename = props.tableAlias;
      useMultiTagsStoreHook().handleTags("push", {
        path: `${props.parentRoute}${typename}/detail`,
        parentPath: route.matched[0].path,
        name: `${typename}Detail`,
        query: { typename },
        meta: {
          title: {
            zh: props.detailDialogTile,
            en: `Add Info`
          },
          showLink: false,
          i18n: false,
          dynamicLevel: 3
        }
      });
      useRuleStoreHook().setTitle(props.detailDialogTile);
      useRuleStoreHook().setTypeName(typename);
      useRuleStoreHook().setValue(obj);
      useRuleStoreHook().setPk(props.primaryKey);
      router.push({
        name: `${typename}Detail`,
        query: { typename }
      });
    };

    return {
      CommonObj,
      beforeSaveDialogCancel,
      batchSaveSubmit,
      tableFormatter,
      deleteData,
      handleSelectionChange,
      formBatchSubmit,
      formSubmit,
      cancelBatchForm,
      cancelForm,
      showBatchUpdate,
      getBaseTableInfo,
      acquireTableInfo,
      getTableList,
      showAdd,
      showEdit,
      handleCurrentPagChange,
      handleSizePagChange,
      handleSortChange,
      resetSearch,
      acquireTable,
      query,
      showBatchAdd,
      showDetails
    };
  }
});

export default CommonNext;
